//
//  ViewController.m
//  MapBoxDemo
//
//  Created by 罗大帅 on 2017/8/8.
//  Copyright © 2017年 wenliaokeji. All rights reserved.
//

#import "ViewController2.h"
#import <Mapbox/Mapbox.h>
@interface ViewController2 () <MGLMapViewDelegate>
@property (weak,nonatomic) MGLMapView *mapView;

@property (strong,nonatomic) UIImage *icon;
@property (strong,nonatomic) UILabel *popup;
@property (strong,nonatomic) UILabel *zoomLevelLabel;
@property (strong,nonatomic) UIButton *changeLevelButton;

@property (assign,nonatomic) BOOL changingFlag;

@end

@implementation ViewController2

#define firstLevel 2.0
#define secondLevel 5.0
#define thirdLevel 9.0
#define fourthLevel 14.0
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor blueColor];
    // Do any additional setup after loading the view, typically from a nib.
    MGLMapView *mapView = [[MGLMapView alloc] initWithFrame:self.view.bounds];
    
    mapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    mapView.minimumZoomLevel = firstLevel;
    mapView.maximumZoomLevel = fourthLevel;
    // Set the map’s center coordinate and zoom level.
    [mapView setCenterCoordinate:CLLocationCoordinate2DMake(59.31, 18.06)
                       zoomLevel:9
                        animated:NO];
    mapView.delegate = self;
    [self.view addSubview:mapView];
    self.mapView = mapView;
    
    self.icon = [UIImage imageNamed:@"port"];
    
    UILabel *zoomLevelLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 500, 50)];
    [self.view addSubview:zoomLevelLabel];
    self.zoomLevelLabel = zoomLevelLabel;
    
    UIButton *changeLevelButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 50, 50, 50)];
    changeLevelButton.backgroundColor = [UIColor blueColor];
    [self.view addSubview:changeLevelButton];
    self.changeLevelButton = changeLevelButton;
    
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
// Wait until the style is loaded before modifying the map style.
- (void)mapView:(MGLMapView *)mapView didChangeUserTrackingMode:(MGLUserTrackingMode)mode animated:(BOOL)animated{
    NSLog(@"%s",__func__);
}
- (void)mapView:(MGLMapView *)mapView regionWillChangeAnimated:(BOOL)animated{
    NSLog(@"%s,%f",__func__,mapView.zoomLevel);
}
- (void)mapViewRegionIsChanging:(MGLMapView *)mapView{
    NSLog(@"%s,%f",__func__,mapView.zoomLevel);
    [self showPopup:NO animated:NO];
    [self.zoomLevelLabel setText:[NSString stringWithFormat:@"zoomLevel:%f",mapView.zoomLevel]];
}

- (void)mapView:(MGLMapView *)mapView regionDidChangeAnimated:(BOOL)animated{
    NSLog(@"%s,%f",__func__,mapView.zoomLevel);
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    if(self.changingFlag == NO){
        self.changingFlag = YES;
//        if(mapView.zoomLevel >= fourthLevel){//特别小
//            mapView.zoomLevel = fourthLevel;
//        }else if (mapView.zoomLevel >= (secondLevel + (thirdLevel - secondLevel) * 0.5)){
//            mapView.zoomLevel = thirdLevel;
//        }else if (mapView.zoomLevel >= (firstLevel + (secondLevel - firstLevel) * 0.5)){
//            mapView.zoomLevel = secondLevel;
//        }else{
//            mapView.zoomLevel = firstLevel;
//        }
    //    });
        [self.zoomLevelLabel setText:[NSString stringWithFormat:@"zoomLevel:%f",mapView.zoomLevel]];
        self.changingFlag = NO;
    }
}
- (void)addLayer {
    //    MGLSource *source = [[MGLVectorSource alloc] initWithIdentifier:@"population" configurationURL:[NSURL URLWithString:@"mapbox://examples.8fgz4egr"]];
    MGLSource *source = [[MGLVectorSource alloc] initWithIdentifier:@"population" configurationURL:[NSURL URLWithString:@"https://www.mapbox.com/ios-sdk/images/runtime-circle-styles.png"]];
    
    NSDictionary *ethnicities = @{
                                  @"White": [UIColor colorWithRed: 251/255.0 green: 176/255.0 blue: 59/255.0 alpha: 1.0],
                                  @"Black": [UIColor colorWithRed: 34/255.0 green: 59/255.0 blue: 83/255.0 alpha: 1.0],
                                  @"Hispanic": [UIColor colorWithRed: 229/255.0 green: 94/255.0 blue: 94/255.0 alpha: 1.0],
                                  @"Asian": [UIColor colorWithRed: 59/255.0 green: 178/255.0 blue: 208/255.0 alpha: 1.0],
                                  @"Other": [UIColor colorWithRed: 204/255.0 green: 204/255.0 blue: 204/255.0 alpha: 1.0],
                                  };
    
    
    [self.mapView.style addSource:source];
    
    // Create a new layer for each ethnicity/circle color.
    for (NSString *key in [ethnicities allKeys]) {
        // Each layer should have a unique identifier.
        MGLCircleStyleLayer *layer = [[MGLCircleStyleLayer alloc] initWithIdentifier:[NSString stringWithFormat:@"population-%@", key] source:source];
        
        // Specifying the `sourceLayerIdentifier` is required for a vector tile source. This is the json attribute that wraps the data in the source.
        layer.sourceLayerIdentifier = @"sf2010";
        
        // Use a style function to smoothly adjust the circle radius from 2pt to 180pt between zoom levels 12 and 22. The `interpolationBase` parameter allows the values to interpolate along an exponential curve.
        layer.circleRadius = [MGLStyleValue valueWithInterpolationMode:MGLInterpolationModeExponential
                                                           cameraStops:@{
                                                                         @12: [MGLStyleValue valueWithRawValue:@2],
                                                                         @22: [MGLStyleValue valueWithRawValue:@180]
                                                                         }
                                                               options: @{MGLStyleFunctionOptionDefaultValue:@1.75}];
        layer.circleOpacity = [MGLStyleValue valueWithRawValue:@0.7];
        
        // Set the circle color to match the ethnicity.
        layer.circleColor = [MGLStyleValue valueWithRawValue:ethnicities[key]];
        
        // Use an NSPredicate to filter to just one ethnicity for this layer.
        layer.predicate = [NSPredicate predicateWithFormat:@"ethnicity == %@", key];
        
        [self.mapView.style addLayer:layer];
    }
}
- (void)mapView:(MGLMapView *)mapView didFinishLoadingStyle:(MGLStyle *)style {
    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"ports" ofType:@"geojson"]];
    
    MGLShapeSource *source = [[MGLShapeSource alloc] initWithIdentifier:@"clusteredPorts" URL:url options:@{
                                                                                                            MGLShapeSourceOptionClustered: @(YES),
                                                                                                            MGLShapeSourceOptionClusterRadius: @(self.icon.size.width)
                                                                                                            }];
    [style addSource:source];
    
    // Use a template image so that we can tint it with the `iconColor` runtime styling property.
    [style setImage:[self.icon imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate] forName:@"icon"];
    
    // Show unclustered features as icons. The `cluster` attribute is built into clustering-enabled source features.
    MGLSymbolStyleLayer *ports = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"ports" source:source];
    ports.iconImageName = [MGLStyleValue valueWithRawValue:@"icon"];
    ports.iconColor = [MGLStyleValue valueWithRawValue:[[UIColor darkGrayColor] colorWithAlphaComponent:0.9]];
    ports.predicate = [NSPredicate predicateWithFormat:@"%K != YES", @"cluster"];
    [style addLayer:ports];
    
    // Color clustered features based on clustered point counts.
    NSDictionary *stops = @{ @20:  [MGLStyleValue valueWithRawValue:[UIColor lightGrayColor]],
                             @50:  [MGLStyleValue valueWithRawValue:[UIColor orangeColor]],
                             @100: [MGLStyleValue valueWithRawValue:[UIColor redColor]],
                             @200: [MGLStyleValue valueWithRawValue:[UIColor purpleColor]] };
    
    // Show clustered features as circles. The `point_count` attribute is built into clustering-enabled source features.
    MGLCircleStyleLayer *circlesLayer = [[MGLCircleStyleLayer alloc] initWithIdentifier:@"clusteredPorts" source:source];
    circlesLayer.circleRadius = [MGLStyleValue valueWithRawValue:@(self.icon.size.width / 2)];
    circlesLayer.circleOpacity = [MGLStyleValue valueWithRawValue:@0.75];
    circlesLayer.circleStrokeColor = [MGLStyleValue valueWithRawValue:[[UIColor whiteColor] colorWithAlphaComponent:0.75]];
    circlesLayer.circleStrokeWidth = [MGLStyleValue valueWithRawValue:@2];
    circlesLayer.circleColor = [MGLSourceStyleFunction
                                functionWithInterpolationMode:MGLInterpolationModeInterval
                                stops:stops
                                attributeName:@"point_count"
                                options:nil];
    circlesLayer.predicate = [NSPredicate predicateWithFormat:@"%K == YES", @"cluster"];
    [style addLayer:circlesLayer];
    
    // Label cluster circles with a layer of text indicating feature count. Per text token convention, wrap the attribute in {}.
    MGLSymbolStyleLayer *numbersLayer = [[MGLSymbolStyleLayer alloc] initWithIdentifier:@"clusteredPortsNumbers" source:source];
    numbersLayer.textColor = [MGLStyleValue valueWithRawValue:[UIColor whiteColor]];
    numbersLayer.textFontSize = [MGLStyleValue valueWithRawValue:@(self.icon.size.width / 2)];
    numbersLayer.iconAllowsOverlap = [MGLStyleValue valueWithRawValue:@(YES)];
    numbersLayer.text = [MGLStyleValue valueWithRawValue:@"{point_count}"];
    numbersLayer.predicate = [NSPredicate predicateWithFormat:@"%K == YES", @"cluster"];
    [style addLayer:numbersLayer];
    
    // Add a tap gesture for zooming in to clusters or showing popups on individual features.
    [self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]];
}

- (void)handleTap:(UITapGestureRecognizer *)tap {
    if (tap.state == UIGestureRecognizerStateEnded) {
        CGPoint point = [tap locationInView:tap.view];
        CGFloat width = self.icon.size.width;
        CGRect rect = CGRectMake(point.x - width / 2, point.y - width / 2, width, width);
        
        // Find cluster circles and/or individual port icons in a touch-sized region around the tap.
        // In theory, we should only find either one cluster (since they don't overlap) or one port
        // (since overlapping ones would be clustered).
        NSArray *clusters = [self.mapView visibleFeaturesInRect:rect inStyleLayersWithIdentifiers:[NSSet setWithObject:@"clusteredPorts"]];
        NSArray *ports    = [self.mapView visibleFeaturesInRect:rect inStyleLayersWithIdentifiers:[NSSet setWithObject:@"ports"]];
        
        if (clusters.count) {
            [self showPopup:NO animated:YES];
            MGLPointFeature *cluster = (MGLPointFeature *)clusters.firstObject;
            [self.mapView setCenterCoordinate:cluster.coordinate zoomLevel:(self.mapView.zoomLevel + 1) animated:YES];
        } else if (ports.count) {
            MGLPointFeature *port = ((MGLPointFeature *)ports.firstObject);
            
            if (!self.popup) {
                self.popup = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 40)];
                self.popup.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.9];
                self.popup.layer.cornerRadius = 4;
                self.popup.layer.masksToBounds = YES;
                self.popup.textAlignment = NSTextAlignmentCenter;
                self.popup.lineBreakMode = NSLineBreakByTruncatingTail;
                self.popup.font = [UIFont systemFontOfSize:16];
                self.popup.textColor = [UIColor blackColor];
                self.popup.alpha = 0;
                [self.view addSubview:self.popup];
            }
            
            self.popup.text = [NSString stringWithFormat:@"%@", [port attributeForKey:@"name"]];
            CGSize size = [self.popup.text sizeWithAttributes:@{ NSFontAttributeName: self.popup.font }];
            self.popup.bounds = CGRectInset(CGRectMake(0, 0, size.width, size.height), -10, -10);
            point = [self.mapView convertCoordinate:port.coordinate toPointToView:self.mapView];
            self.popup.center = CGPointMake(point.x, point.y - 50);
            
            if (self.popup.alpha < 1) {
                [self showPopup:YES animated:YES];
            }
        } else {
            [self showPopup:NO animated:YES];
        }
    }
}

- (void)showPopup:(BOOL)shouldShow animated:(BOOL)animated {
    CGFloat alpha = (shouldShow ? 1 : 0);
    if (animated) {
        __typeof__(self) __weak weakSelf = self;
        [UIView animateWithDuration:0.25 animations:^{
            weakSelf.popup.alpha = alpha;
        }];
    } else {
        self.popup.alpha = alpha;
    }
}

@end
